package com.codeoss.framework.webide.service.impl;

import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.codeoss.framework.context.YunContext;
import com.codeoss.framework.data.metadata.Column;
import com.codeoss.framework.data.metadata.Query;
import com.codeoss.framework.data.metadata.Restrictions;
import com.codeoss.framework.data.metadata.Table;
import com.codeoss.framework.data.store.ITableStore;
import com.codeoss.framework.db.util.ValueNamePairUtil;
import com.codeoss.framework.util.StringUtils;
import com.codeoss.framework.util.ValueNamePair;
import com.codeoss.framework.webide.request.WorkflowWizardDialogRequest;
import com.codeoss.framework.webide.response.WorkflowWizardDialogResponse;
import com.codeoss.framework.webide.service.IWorkflowWizardDialogService;
import com.codeoss.module.ir.model.IrModel;
import com.codeoss.module.ir.model.IrPage;
import com.codeoss.module.ir.model.IrWorkflow;
import com.codeoss.module.ir.service.IIrDictService;
import com.codeoss.module.ir.service.IIrModelService;
import com.codeoss.module.ir.service.IIrPageService;
import com.codeoss.module.ir.service.IIrWorkflowService;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;

@Service
public class WorkflowWizardDialogService implements IWorkflowWizardDialogService {
	@Autowired
	private ObjectMapper objectMapper;
	@Autowired
	private IIrWorkflowService irWorkflowService;
	@Autowired
	private IIrModelService irModelService;
	@Autowired
	private IIrDictService irDictService;
	@Autowired
	private IIrPageService irPageService;
	@Autowired
	private ITableStore tableStore;
	@Autowired
	private ValueNamePairUtil valueNamePairUtil;

	@Override
	@Transactional
	public WorkflowWizardDialogResponse onFinish(WorkflowWizardDialogRequest request) {
		// TODO Auto-generated method stub
		WorkflowWizardDialogResponse workflowWizardDialogResponse = new WorkflowWizardDialogResponse();
		ObjectNode objectNode = null;
		try {
			objectNode = (ObjectNode) objectMapper.readTree(request.getJson());
		} catch (Exception e) {
			// TODO Auto-generated catch block
			throw new RuntimeException(e);
		}
		String moduleType = objectNode.get("moduleTypeSelectPage").get("moduleType").asText();
		String code = objectNode.get("workflowBaseInfoPage").get("code").asText();

		QueryWrapper<IrWorkflow> query = new QueryWrapper<IrWorkflow>();
		query.eq("code", code);
		IrWorkflow irWorkflow = irWorkflowService.getOne(query);
		if (irWorkflow != null) {
			throw new RuntimeException("此编码已经存在");
		}
		String name = objectNode.get("workflowBaseInfoPage").get("name").asText();
		String description = objectNode.get("workflowBaseInfoPage").get("description").asText();
		String formCode = objectNode.get("formPageSelectPage").get("formCode").asText();
		String mobileFormCode = objectNode.get("formPageSelectPage").get("mobileFormCode").asText();
		ArrayNode data = (ArrayNode) objectNode.get("approvalConfigPage").get("data");
		String tableName = objectNode.get("modelSelectPage").get("tableName").asText();
		ArrayNode displayColumListArrayNode = (ArrayNode) objectNode.get("modelSelectPage").get("displayColumList");
		irWorkflow = new IrWorkflow();
		irWorkflow.setModuleType(moduleType);
		irWorkflow.setCode(code);
		irWorkflow.setName(name);
		irWorkflow.setDescription(description);
		irWorkflow.setFormCode(formCode);
		irWorkflow.setMobileFormCode(mobileFormCode);

		IrModel irModel = irModelService.getIrModelByTableName(tableName);
		irWorkflow.setIrModelId(irModel.getId());
		StringBuilder displayColumnListBuilder = new StringBuilder();
		for (int i = 0; i < displayColumListArrayNode.size(); i++) {
			if (i > 0) {
				displayColumnListBuilder.append(",");
			}
			displayColumnListBuilder.append(displayColumListArrayNode.get(i).asText());
		}
		irWorkflow.setDisplayColumnList(displayColumnListBuilder.toString());

		ObjectNode wkfObjectNode = objectMapper.createObjectNode();
		wkfObjectNode.put("code", code);
		wkfObjectNode.put("formCode", formCode);
		wkfObjectNode.put("mobileFormCode", mobileFormCode);

		ArrayNode nodeArray = objectMapper.createArrayNode();
		wkfObjectNode.set("nodeList", nodeArray);

		ArrayNode lineArray = objectMapper.createArrayNode();
		wkfObjectNode.set("lineList", lineArray);

		int id = 1;
		int distance = 72;
		int startY = 29;
		ObjectNode startObjectNode = objectMapper.createObjectNode();
		nodeArray.add(startObjectNode);
		startObjectNode.put("id", "node_" + id);
		startObjectNode.put("type", "start");
		startObjectNode.put("top", startY + "px");
		startObjectNode.put("left", "111px");

		id++;
		startY += distance;
		ObjectNode inputTaskObjectNode = objectMapper.createObjectNode();
		nodeArray.add(inputTaskObjectNode);
		inputTaskObjectNode.put("id", "node_" + id);
		inputTaskObjectNode.put("type", "task");
		inputTaskObjectNode.put("name", "填写节点");
		inputTaskObjectNode.put("assignmentExpression", "userContext.getUsername()");
		inputTaskObjectNode.put("canUserInput", true);
		inputTaskObjectNode.put("completeRule", "all");
		inputTaskObjectNode.put("top", startY + "px");
		inputTaskObjectNode.put("left", "81px");
		inputTaskObjectNode.put("width", "160px");
		startY += 50;

		id++;
		ObjectNode lineObjectNode = objectMapper.createObjectNode();
		lineArray.add(lineObjectNode);
		lineObjectNode.put("from", startObjectNode.get("id").asText());
		lineObjectNode.put("to", inputTaskObjectNode.get("id").asText());
		lineObjectNode.put("name", "line_" + id);

		String previous = inputTaskObjectNode.get("id").asText();
		for (int i = 0; i < data.size(); i++) {
			ObjectNode taskDataObjectNode = (ObjectNode) data.get(i);
			String taskName = taskDataObjectNode.get("name").asText();
			ArrayNode roleValueList = (ArrayNode) taskDataObjectNode.get("roleValueList");
			ArrayNode userValueList = (ArrayNode) taskDataObjectNode.get("userValueList");
			String assignmentExpression = taskDataObjectNode.get("assignmentExpression").asText();
			id++;
			startY += distance;
			ObjectNode taskObjectNode = objectMapper.createObjectNode();
			nodeArray.add(taskObjectNode);
			taskObjectNode.put("id", "node_" + id);
			taskObjectNode.put("type", "task");
			taskObjectNode.put("name", taskName);
			if (roleValueList.size() > 0) {
				StringBuilder sb = new StringBuilder();
				for (int j = 0; j < roleValueList.size(); j++) {
					if (j > 0) {
						sb.toString();
					}
					sb.append(roleValueList.get(j).asText());
				}
				taskObjectNode.put("roleAssignment", sb.toString());
			}
			if (userValueList.size() > 0) {
				StringBuilder sb = new StringBuilder();
				for (int j = 0; j < userValueList.size(); j++) {
					if (j > 0) {
						sb.toString();
					}
					sb.append(userValueList.get(j).asText());
				}
				taskObjectNode.put("userAssignment", sb.toString());
			}
			if (!StringUtils.isEmpty(assignmentExpression)) {
				taskObjectNode.put("assignmentExpression", assignmentExpression);
			}
			taskObjectNode.put("completeRule", "all");
			taskObjectNode.put("top", startY + "px");
			taskObjectNode.put("left", "81px");
			taskObjectNode.put("width", "160px");
			startY += 50;
			id++;
			lineObjectNode = objectMapper.createObjectNode();
			lineArray.add(lineObjectNode);
			lineObjectNode.put("from", previous);
			lineObjectNode.put("to", taskObjectNode.get("id").asText());
			lineObjectNode.put("name", "line_" + id);
			previous = taskObjectNode.get("id").asText();
		}

		id++;
		startY += distance;
		ObjectNode endObjectNode = objectMapper.createObjectNode();
		nodeArray.add(endObjectNode);
		endObjectNode.put("id", "node_" + id);
		endObjectNode.put("type", "end");
		endObjectNode.put("top", startY + "px");
		endObjectNode.put("left", "111px");

		id++;
		lineObjectNode = objectMapper.createObjectNode();
		lineArray.add(lineObjectNode);
		lineObjectNode.put("from", previous);
		lineObjectNode.put("to", endObjectNode.get("id").asText());
		lineObjectNode.put("name", "line_" + id);

		id++;
		irWorkflow.setCurrentElementId(id);
		try {
			String jsonContent = objectMapper.writeValueAsString(wkfObjectNode);
			irWorkflow.setJsonContent(jsonContent);
		} catch (JsonProcessingException e) {
			// TODO Auto-generated catch block
			throw new RuntimeException(e);
		}
		irWorkflowService.insert(irWorkflow);

		ValueNamePair item = new ValueNamePair(irWorkflow.getName(), irWorkflow.getCode());
		workflowWizardDialogResponse.setItem(item);
		return workflowWizardDialogResponse;
	}

	@Override
	public WorkflowWizardDialogResponse initModuleTypeSelectPage() {
		// TODO Auto-generated method stub
		WorkflowWizardDialogResponse workflowWizardDialogResponse = new WorkflowWizardDialogResponse();
		List<ValueNamePair> moduleTypeList = irDictService.getPairListByCode("moduleType");
		workflowWizardDialogResponse.setModuleTypeList(moduleTypeList);
		return workflowWizardDialogResponse;
	}

	@Override
	public WorkflowWizardDialogResponse initApprovalConfigPage() {
		// TODO Auto-generated method stub
		WorkflowWizardDialogResponse workflowWizardDialogResponse = new WorkflowWizardDialogResponse();
		YunContext yunContext = YunContext.getCurrentContext();
		Table userTable = tableStore.get("res_user");
		Query userQuery=new Query();
		userQuery.add(Restrictions.isNull("res_partner_id"));
		List<ValueNamePair> userPairList = valueNamePairUtil.getValueNamePairList(yunContext, userTable, userQuery, false,false);
		workflowWizardDialogResponse.setUserPairList(userPairList);

		Table roleTable = tableStore.get("res_role");
		List<ValueNamePair> rolePairList = valueNamePairUtil.getValueNamePairList(yunContext, roleTable, null, false,false);
		workflowWizardDialogResponse.setRolePairList(rolePairList);
		return workflowWizardDialogResponse;
	}

	@Override
	public WorkflowWizardDialogResponse initFormPageSelectPage() {
		// TODO Auto-generated method stub
		WorkflowWizardDialogResponse workflowWizardDialogResponse = new WorkflowWizardDialogResponse();

		QueryWrapper<IrPage> pcQueryWrapper = new QueryWrapper<IrPage>();
		pcQueryWrapper.eq("device", "pc");
		List<IrPage> pageList = irPageService.list(pcQueryWrapper);
		List<ValueNamePair> formCodeList = new ArrayList<ValueNamePair>();
		workflowWizardDialogResponse.setFormCodeList(formCodeList);
		for (int i = 0; i < pageList.size(); i++) {
			IrPage irPage = pageList.get(i);
			ValueNamePair pair = new ValueNamePair(irPage.getName(), irPage.getPageCode());
			formCodeList.add(pair);
		}

		QueryWrapper<IrPage> mobileQueryWrapper = new QueryWrapper<IrPage>();
		mobileQueryWrapper.eq("device", "mobile");
		List<IrPage> mobilePageList = irPageService.list(mobileQueryWrapper);
		List<ValueNamePair> mobileFormCodeList = new ArrayList<ValueNamePair>();
		workflowWizardDialogResponse.setMobileFormCodeList(mobileFormCodeList);
		for (int i = 0; i < mobilePageList.size(); i++) {
			IrPage irPage = mobilePageList.get(i);
			ValueNamePair pair = new ValueNamePair(irPage.getName(), irPage.getPageCode());
			mobileFormCodeList.add(pair);
		}

		return workflowWizardDialogResponse;
	}

	@Override
	public WorkflowWizardDialogResponse initModelSelectPage() {
		// TODO Auto-generated method stub
		WorkflowWizardDialogResponse workflowWizardDialogResponse = new WorkflowWizardDialogResponse();
		List<ValueNamePair> tableList = new ArrayList<ValueNamePair>();
		workflowWizardDialogResponse.setTableList(tableList);
		List<IrModel> modelList = irModelService.list();
		for (int i = 0; i < modelList.size(); i++) {
			IrModel irModel = modelList.get(i);
			ValueNamePair pair = new ValueNamePair(irModel.getName() + "(" + irModel.getTableName() + ")",
					irModel.getTableName());
			tableList.add(pair);
		}
		return workflowWizardDialogResponse;
	}

	@Override
	public WorkflowWizardDialogResponse onTableSelectChangeHandler(String tableName) {
		// TODO Auto-generated method stub
		WorkflowWizardDialogResponse workflowWizardDialogResponse = new WorkflowWizardDialogResponse();
		Table table = tableStore.get(tableName);
		List<Column> columnList = table.getAllColumnList();
		List<ValueNamePair> pairList = new ArrayList<ValueNamePair>();
		workflowWizardDialogResponse.setColumnList(pairList);
		for (int i = 0; i < columnList.size(); i++) {
			Column column = columnList.get(i);
			ValueNamePair pair = new ValueNamePair(column.getName() + "(" + column.getColumnName() + ")",
					column.getColumnName());
			pairList.add(pair);
		}
		return workflowWizardDialogResponse;
	}

}
